import Storage from './Storage.js'
import MysApi from './MysApi.js'

/**
 * 用户管理类
 */
export default class UserManager {
  constructor() {
    this.storage = Storage
  }

  /**
   * 从 Yunzai 主体获取用户 Cookie 和 UID
   * @param {Object} e - 消息事件对象
   * @returns {Promise<Object|null>} { uid, cookie } 或 null
   */
  async getYunzaiCookie(e) {
    try {
      // 方式1：尝试通过 NoteUser 获取（Yunzai 主体方式）- 优先使用这个，因为它返回完整 Cookie
      try {
        // 动态导入以避免依赖问题
        const NoteUser = await import('../../../plugins/genshin/model/mys/NoteUser.js').then(m => m.default)
        const user = await NoteUser.create(e.user_id)
        
        if (user && user.hasCk) {
          // 获取MysUser对象
          const mysUser = user.getMysUser(e)
          if (mysUser && mysUser.ck) {
            const uid = user.getUid('gs') || mysUser.uid
            
            // 自动清理 Cookie 格式
            const cookieParts = mysUser.ck.split(';')
            const cleanCookie = cookieParts
              .map(p => p.trim())
              .filter(p => p.length > 0)
              .join(';')
            
            if (cleanCookie !== mysUser.ck) {
              mysUser.ck = cleanCookie
            }
            
            return {
              uid,
              cookie: mysUser.ck,
              source: 'yunzai'
            }
          }
        }
      } catch (err) {
        // Yunzai 主体模块不存在，忽略错误
        logger.debug('[签到插件] NoteUser 获取失败:', err.message)
      }

      // 方式2：尝试通过 e.runtime 获取（喵喵插件方式）- 作为备用方案
      if (e.runtime && e.runtime.getMysInfo) {
        try {
          const mysInfo = await e.runtime.getMysInfo('cookie')
          if (mysInfo && mysInfo.uid && mysInfo.ckInfo && mysInfo.ckInfo.ck) {
            logger.mark('[签到插件] 通过 runtime.getMysInfo 获取 Cookie（备用）')
            return {
              uid: mysInfo.uid,
              cookie: mysInfo.ckInfo.ck,
              source: 'runtime'
            }
          }
        } catch (err) {
          logger.debug('[签到插件] runtime.getMysInfo 获取失败:', err.message)
        }
      }

      return null
    } catch (error) {
      logger.error('[签到插件] 从 Yunzai 获取 Cookie 失败:', error)
      return null
    }
  }

  /**
   * 获取用户 Cookie（优先从 Yunzai，其次从本地）
   * @param {Number} qq - 用户QQ
   * @param {Object} e - 消息事件对象
   * @returns {Promise<Object|null>} { uid, cookie, source }
   */
  async getCookie(qq, e = null) {
    // 1. 尝试从 Yunzai 获取
    if (e) {
      const yunzaiCookie = await this.getYunzaiCookie(e)
      if (yunzaiCookie) {
        // 验证 Yunzai Cookie 是否包含签到必需字段
        const cookieObj = this.parseCookie(yunzaiCookie.cookie)
        
        // 检查签到核心字段
        const hasLtoken = !!cookieObj.ltoken
        const hasLtuid = !!cookieObj.ltuid
        
        // 检查账号字段（V1或V2版本）
        const hasCookieToken = !!(cookieObj.cookie_token || cookieObj.cookie_token_v2)
        const hasAccountId = !!(cookieObj.account_id || cookieObj.account_id_v2)
        
        // 签到需要所有这些字段
        const hasSignFields = hasLtoken && hasLtuid && hasCookieToken && hasAccountId
        
        if (hasSignFields) {
          // 自动同步完整Cookie到本地
          await this.autoSyncYunzaiCookie(qq, yunzaiCookie.uid, yunzaiCookie.cookie)
          return yunzaiCookie
        } else {
          logger.warn(`[签到插件] Yunzai Cookie 不完整，尝试使用本地Cookie`)
        }
      }
    }

    // 2. 从本地存储获取
    const user = this.storage.getUser(qq)
    if (user && user.cookie && user.uid) {
      return {
        uid: user.uid,
        cookie: user.cookie,
        source: 'local'
      }
    }

    return null
  }

  /**
   * 获取指定游戏的UID
   * @param {Number} qq - 用户QQ
   * @param {String} game - 游戏类型 (gs: 原神, sr: 星铁)
   * @param {Object} e - 消息事件对象（可选）
   * @returns {Promise<String|null>} 游戏UID
   */
  async getGameUid(qq, game = 'gs', e = null) {
    try {
      // 1. 优先从本地存储获取（新版支持分游戏存储）
      const localUid = this.storage.getUserUid(qq, game)
      if (localUid) {
        logger.debug(`[签到插件] 从本地获取${game}UID: ${localUid}`)
        return localUid
      }

      // 2. 尝试从 Yunzai 的 NoteUser 获取
      if (e) {
        try {
          const NoteUser = (await import('../../../lib/plugins/plugin.js')).default.prototype.e?.runtime?.NoteUser
          if (NoteUser) {
            const user = new NoteUser(e)
            const uid = user.getUid(game)
            if (uid) {
              const uidStr = String(uid)
              // 保存到本地
              this.storage.saveUserUid(qq, game, uidStr)
              logger.info(`[签到插件] 从Yunzai获取并保存${game}UID: ${uidStr}`)
              return uidStr
            }
          }
        } catch (err) {
          // 静默失败
        }
      }

      // 3. 如果是原神，尝试从 Cookie 数据中获取（兼容旧版）
      if (game === 'gs') {
        const cookieData = await this.getCookie(qq, e)
        if (cookieData && cookieData.uid) {
          // 保存到本地（新版格式）
          this.storage.saveUserUid(qq, game, cookieData.uid)
          logger.info(`[签到插件] 从Cookie获取并保存原神UID: ${cookieData.uid}`)
          return cookieData.uid
        }
      }

      return null
    } catch (error) {
      logger.error(`[签到插件] 获取${game}UID失败:`, error)
      return null
    }
  }

  /**
   * 通过API获取游戏UID
   * @param {String} qq - 用户QQ（用于保存UID，可选）
   * @param {String} cookie - Cookie字符串
   * @param {String} game - 游戏类型 (gs, sr)
   * @returns {Promise<String|null>} 游戏UID
   */
  async getGameUidFromApi(qq, cookie, game = 'gs') {
    try {
      const MysApi = (await import('./MysApi.js')).default
      
      // 使用临时UID创建API实例（只需要Cookie）
      const api = new MysApi('100000000', cookie, { game })
      
      // 获取游戏角色信息
      const rolesData = await api.getGameRoles()
      
      if (rolesData.retcode !== 0) {
        logger.warn(`[签到插件] 获取游戏角色失败: ${rolesData.message}`)
        return null
      }
      
      if (!rolesData.data || !rolesData.data.list || rolesData.data.list.length === 0) {
        logger.warn(`[签到插件] 该账号没有${game}游戏角色`)
        return null
      }
      
      // 获取第一个角色的UID
      const uid = rolesData.data.list[0].game_uid
      
      // 如果提供了qq，保存到本地
      if (qq) {
        this.storage.saveUserUid(qq, game, uid)
        logger.info(`[签到插件] 从API获取并保存${game}UID: ${uid}`)
      }
      
      return uid
    } catch (error) {
      logger.error(`[签到插件] 通过API获取UID失败:`, error)
      return null
    }
  }

  /**
   * 自动同步 Yunzai 主体的完整 Cookie 到本地
   * @param {String} qq - 用户QQ
   * @param {String} uid - UID
   * @param {String} cookie - 完整Cookie
   */
  async autoSyncYunzaiCookie(qq, uid, cookie) {
    try {
      const localUser = this.storage.getUser(qq)
      
      // 自动保存到本地
      if (!localUser || localUser.uid !== uid || localUser.cookie !== cookie) {
        this.storage.saveUserCookie(qq, cookie, uid)
      }
    } catch (error) {
      logger.error('[签到插件] 自动同步 Cookie 失败:', error)
    }
  }

  /**
   * 解析Cookie字符串
   */
  parseCookie(cookieStr) {
    const cookie = {}
    const cleanStr = cookieStr.replace(/#|'|"/g, '').trim()
    
    cleanStr.split(';').forEach((item) => {
      const trimmedItem = item.trim()
      if (!trimmedItem) return
      
      const equalIndex = trimmedItem.indexOf('=')
      if (equalIndex === -1) return
      
      const key = trimmedItem.substring(0, equalIndex).trim()
      const value = trimmedItem.substring(equalIndex + 1).trim()
      
      if (key && value && value !== 'undefined') {
        cookie[key] = value
        logger.debug(`[签到插件] 解析Cookie字段: ${key}=${value.substring(0, 20)}...`)
      }
    })

    logger.debug(`[签到插件] Cookie解析结果:`, Object.keys(cookie))
    return cookie
  }

  /**
   * 验证Cookie是否完整
   */
  validateCookie(cookie) {
    // 签到需要的必要字段
    const requiredForSign = ['ltoken', 'ltuid']
    const hasSignFields = requiredForSign.every(field => cookie[field])
    
    if (!hasSignFields) {
      return {
        valid: false,
        message: 'Cookie不完整，签到需要 ltoken 和 ltuid 字段\n请确保Cookie包含完整内容'
      }
    }
    
    // V1或V2版本的cookie_token
    const requiredFields = ['cookie_token', 'account_id']
    const requiredFieldsV2 = ['cookie_token_v2', 'account_id_v2']
    
    const hasV1 = requiredFields.every(field => cookie[field])
    const hasV2 = requiredFieldsV2.every(field => cookie[field])
    
    if (!hasV1 && !hasV2) {
      return {
        valid: false,
        message: 'Cookie不完整，请确保包含 cookie_token 和 account_id（或V2版本）'
      }
    }

    return { valid: true }
  }

  /**
   * 格式化Cookie
   */
  formatCookie(cookieObj) {
    let cookie = ''
    
    logger.debug(`[签到插件] 格式化Cookie前检查:`)
    logger.debug(`  - ltoken: ${cookieObj.ltoken ? '存在' : '不存在'} (${typeof cookieObj.ltoken})`)
    logger.debug(`  - ltuid: ${cookieObj.ltuid ? '存在' : '不存在'}`)
    logger.debug(`  - cookie_token: ${cookieObj.cookie_token ? '存在' : '不存在'}`)
    logger.debug(`  - account_id: ${cookieObj.account_id ? '存在' : '不存在'}`)
    
    // 签到必需的字段
    if (cookieObj.ltoken && cookieObj.ltoken !== 'undefined') {
      cookie += `ltoken=${cookieObj.ltoken};`
    } else {
      logger.warn(`[签到插件] ltoken字段缺失或无效: ${cookieObj.ltoken}`)
    }
    
    if (cookieObj.ltuid && cookieObj.ltuid !== 'undefined') {
      cookie += `ltuid=${cookieObj.ltuid};`
    }
    
    // 优先使用V2版本
    if (cookieObj.cookie_token_v2 && cookieObj.account_id_v2) {
      cookie += `cookie_token=${cookieObj.cookie_token_v2};account_id=${cookieObj.account_id_v2};`
      if (cookieObj.ltoken_v2) {
        cookie += `ltoken_v2=${cookieObj.ltoken_v2};`
      }
      if (cookieObj.ltmid_v2) {
        cookie += `ltmid_v2=${cookieObj.ltmid_v2};`
      }
      if (cookieObj.account_mid_v2) {
        cookie += `account_mid_v2=${cookieObj.account_mid_v2};`
      }
    } else {
      // 使用V1版本
      if (cookieObj.cookie_token && cookieObj.cookie_token !== 'undefined') {
        cookie += `cookie_token=${cookieObj.cookie_token};`
      }
      if (cookieObj.account_id && cookieObj.account_id !== 'undefined') {
        cookie += `account_id=${cookieObj.account_id};`
      }
    }
    
    logger.debug(`[签到插件] 格式化后的Cookie: ${cookie.substring(0, 100)}...`)
    return cookie
  }

  /**
   * 删除Cookie
   */
  deleteCookie(qq) {
    const user = this.storage.getUser(qq)
    if (!user) {
      return {
        success: false,
        message: '未找到绑定信息'
      }
    }

    this.storage.deleteUser(qq)
    logger.info(`[签到插件] QQ:${qq} 删除Cookie成功`)

    return {
      success: true,
      message: 'Cookie已删除'
    }
  }

  /**
   * 获取用户Cookie
   */
  getUserCookie(qq) {
    return this.storage.getUserCookie(qq)
  }

  /**
   * 获取用户信息
   */
  getUserInfo(qq) {
    const user = this.storage.getUser(qq)
    if (!user) {
      return null
    }

    return {
      uid: user.uid,
      cookie: user.cookie,
      autoSign: this.storage.getUserAutoSign(qq), // 返回 { gs: boolean, sr: boolean }
      pushConfig: this.storage.getUserPushConfig(qq), // 推送配置
      updateTime: user.updateTime
    }
  }

  /**
   * 设置自动签到
   * @param {string} qq - 用户QQ号
   * @param {string} game - 游戏标识 ('gs', 'sr', 'all')
   * @param {boolean} enabled - 是否开启
   */
  setAutoSign(qq, game, enabled) {
    const user = this.storage.getUser(qq)
    if (!user) {
      return {
        success: false,
        message: '请先绑定Cookie'
      }
    }

    this.storage.setUserAutoSign(qq, game, enabled)
    
    const gameNames = { gs: '原神', sr: '星铁', all: '全部游戏' }
    const gameName = gameNames[game] || game
    logger.info(`[签到插件] QQ:${qq} ${enabled ? '开启' : '关闭'} ${gameName}自动签到`)

    return {
      success: true,
      message: `已${enabled ? '开启' : '关闭'}自动签到`
    }
  }

  /**
   * 设置推送配置
   * @param {string} qq - 用户QQ号
   * @param {object} config - 推送配置
   */
  setPushConfig(qq, config) {
    const user = this.storage.getUser(qq)
    if (!user) {
      return {
        success: false,
        message: '请先绑定Cookie'
      }
    }

    this.storage.setUserPushConfig(qq, config)
    
    return {
      success: true,
      message: '推送配置已更新'
    }
  }

  /**
   * 设置开启自动签到的群聊
   * @param {string} qq - 用户QQ号
   * @param {string} groupId - 群聊ID
   */
  setAutoSignGroup(qq, groupId) {
    return this.storage.setUserAutoSignGroup(qq, groupId)
  }

  /**
   * 检查用户是否已绑定
   */
  isUserBound(qq) {
    const user = this.storage.getUser(qq)
    return !!(user && user.cookie && user.uid)
  }

  /**
   * 获取用户签到统计
   */
  getUserStats(qq) {
    if (!this.isUserBound(qq)) {
      return null
    }

    const stats = this.storage.getUserSignStats(qq)
    const todayLog = this.storage.getTodaySignLog(qq)

    return {
      ...stats,
      signedToday: !!todayLog,
      todayResult: todayLog?.result
    }
  }
}

